package aimis.service;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import aimis.domain.Authority;
import aimis.repo.UserRepo;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Service
public class UserService {
    @Autowired
    private UserRepo userRepo;
    public static String SECRET = "sdjhakdhajdklsl;o653632AFEGH";
    public String genToken(String loginName)
    {
        return JWT.create()
                .withClaim("loginName", loginName)
                .withClaim("UUID", UUID.randomUUID().toString()) //想伪造除非知道这个UUID
                .withIssuedAt(new Date())
                .sign(Algorithm.HMAC256(SECRET));
    }
    @Transactional
    public UserDetails getUserDetails(String token) {
        aimis.domain.User user=getUserFromToken(token);
        org.springframework.security.core.userdetails.User.UserBuilder builder = User.builder();
        builder.authorities(getAuthorityNames(user));
        builder.username(user.getLoginName());
        builder.password(user.getPassword());
        return builder.build();
    }
    @Transactional
    public aimis.domain.User getUserFromToken(String token){
        DecodedJWT djwt = JWT.decode(token);
        var loginName = djwt.getClaim("loginName").asString();
        aimis.domain.User user = userRepo.findByLoginName(loginName);
        return user;
    }
    public Set<Authority> getAuthorities(aimis.domain.User user) {
        Set<Authority> authorities = new HashSet<>();

        for (var role : user.getRoles()) {
            for (var i : role.getAuthorities()) {
                authorities.add(i);
            }
        }

        return authorities;
    }
    public String[] getAuthorityNames(aimis.domain.User user)
    {
        var authorities = getAuthorities(user).stream().map(
                (authority) -> {
                    return authority.getName();
                }
        ).toList();
        return authorities.toArray(new String[authorities.size()]);
    }
}
